package com.platform.server.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

import org.apache.log4j.Logger;

public class HttpRequestUtil {
	public static final Logger log = Logger.getLogger(HttpRequestUtil.class);

	/**
	 * 通过get方式发送请求，默认跳过NULL值，即不发送value=null的key
	 * 
	 * @param url
	 * @param params
	 *            参数
	 * @return
	 * @throws Exception
	 */
	public static String sendRequestByGet(String url, Map<String, Object> params) throws IOException {
		return sendRequestByGet(url, params, false);
	}

	/**
	 * 通过get方式发送请求
	 * 
	 * @param url
	 * @param params
	 *            参数
	 * @param skipNull
	 *            是否跳过NULL值，true则不发送value=null的key，否则发送value=
	 * @return
	 * @throws Exception
	 */
	public static String sendRequestByGet(String url, Map<String, Object> params, boolean skipNull) throws IOException {
		if (null == url || "".equals(url.trim())) {
			throw new IOException("url is null...");
		}
		OutputStreamWriter out = null;
		BufferedReader in = null;
		StringBuilder connResult = new StringBuilder("");
		String fullUrl = "";
		try {
			StringBuilder builder = new StringBuilder(url);
			if (null != params && params.size() > 0) {
				builder.append("?");
				for (String s : params.keySet()) {
					if (null == params.get(s)) {
						if (!skipNull) {
							builder.append(s).append("=").append("&");
						}
						continue;
					}
					if (params.get(s) instanceof Iterable<?>) {
						Iterable<?> ite = (Iterable<?>) params.get(s);
						for (Object i : ite) {
							builder.append(s).append("=").append(i).append("&");
						}
					} else {
						builder.append(s).append("=").append(params.get(s)).append("&");
					}
				}
				builder.delete(builder.length() - 1, builder.length());
			}
			fullUrl = builder.toString();
			log.debug(String.format("http request %s", fullUrl));
			URL destURL = new URL(builder.toString());
			HttpURLConnection urlConn = (HttpURLConnection) destURL.openConnection();
			urlConn.setConnectTimeout(5000);
			urlConn.setReadTimeout(40000);
			urlConn.setDoOutput(true);
			urlConn.setDoInput(true);
			urlConn.setAllowUserInteraction(false);
			urlConn.setUseCaches(false);
			urlConn.setRequestMethod("GET");
			urlConn.connect();
			// 响应编码
			String contentType = urlConn.getHeaderField("Content-Type");
			String encode = "UTF-8";
			int index = -1;
			if (null != contentType && (index = contentType.indexOf("charset=")) > -1) {
				encode = contentType.substring(index + 8);
			}
			// 返回状态码
			int state = urlConn.getResponseCode();
			if (state < 400) {// 返回状态码<400为正确响应
				in = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), encode));
			} else {
				in = new BufferedReader(new InputStreamReader(urlConn.getErrorStream(), encode));
			}
			String s = null;
			while ((s = in.readLine()) != null) {
				connResult.append(s);
			}
			log.debug(String.format("http request %s, response[code:%d, encode:%s, content:%s]", fullUrl, state,
					encode, connResult.toString()));
		} catch (IOException e) {
			log.error("http request[" + fullUrl + "] error", e);
			throw e;
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				log.error("http request[" + fullUrl + "] error", e);
				throw e;
			}
		}
		return connResult.toString().trim();
	}

	/**
	 * 通过post方式发送请求，默认跳过NULL值，即不发送value=null的key
	 * 
	 * @param url
	 * @param params
	 *            参数
	 * @return
	 * @throws Exception
	 */
	public static String sendRequestByPost(String url, Map<String, Object> params) throws IOException {
		return sendRequestByPost(url, params, false);
	}

	/**
	 * 通过post方式发送请求
	 * 
	 * @param url
	 * @param params
	 *            参数
	 * @param skipNull
	 *            是否跳过NULL值，true则不发送value=null的key，否则发送value=
	 * @return
	 * @throws Exception
	 */
	public static String sendRequestByPost(String url, Map<String, Object> params, boolean skipNull) throws IOException {
		if (null == url || "".equals(url.trim())) {
			throw new IOException("url is null...");
		}
		OutputStreamWriter out = null;
		BufferedReader in = null;
		StringBuilder connResult = new StringBuilder("");
		String fullUrl = "";
		try {
			StringBuilder builder = new StringBuilder();
			if (null != params && params.size() > 0) {
				for (String s : params.keySet()) {
					if (null == params.get(s)) {
						if (!skipNull) {
							builder.append(s).append("=").append("&");
						}
						continue;
					}
					if (params.get(s) instanceof Iterable<?>) {
						Iterable<?> ite = (Iterable<?>) params.get(s);
						for (Object i : ite) {
							builder.append(s).append("=").append(i).append("&");
						}
					} else {
						builder.append(s).append("=").append(params.get(s)).append("&");
					}
				}
				builder.delete(builder.length() - 1, builder.length());
			}
			fullUrl = url + "?" + builder.toString();
			log.debug(String.format("http request %s", fullUrl));
			URL destURL = new URL(url);
			HttpURLConnection urlConn = (HttpURLConnection) destURL.openConnection();
			urlConn.setConnectTimeout(5000);
			urlConn.setReadTimeout(40000);
			urlConn.setDoOutput(true);
			urlConn.setDoInput(true);
			urlConn.setAllowUserInteraction(false);
			urlConn.setUseCaches(false);
			urlConn.setRequestMethod("POST");
			OutputStream oups = urlConn.getOutputStream();
			oups.write(builder.toString().getBytes());
			urlConn.connect();
			// 响应编码
			String contentType = urlConn.getHeaderField("Content-Type");
			String encode = "UTF-8";
			int index = -1;
			if (null != contentType && (index = contentType.indexOf("charset=")) > -1) {
				encode = contentType.substring(index + 8);
			}
			// 返回状态码
			int state = urlConn.getResponseCode();
			if (state < 400) {// 返回状态码<400为正确响应
				in = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), encode));
			} else {
				in = new BufferedReader(new InputStreamReader(urlConn.getErrorStream(), encode));
			}
			String s = null;
			while ((s = in.readLine()) != null) {
				connResult.append(s);
			}
			log.debug(String.format("http request %s, response[code:%d, encode:%s, content:%s]", fullUrl, state,
					encode, connResult.toString()));
			System.out.println(String.format("http request %s, response[code:%d, encode:%s, content:%s]", fullUrl, state,
					encode, connResult.toString()));
		} catch (IOException e) {
			log.error("http request[" + fullUrl + "] error", e);
			throw e;
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				log.error("http request[" + fullUrl + "] error", e);
				throw e;
			}
		}
		return connResult.toString().trim();
	}

	public static String sendRequest(String url, Map<String, Object> params) throws Exception {
		OutputStreamWriter out = null;
		BufferedReader in = null;
		StringBuilder connResult = new StringBuilder("");
		try {
			StringBuilder builder = new StringBuilder(url).append("?");
			for (String s : params.keySet()) {
				if (null == params.get(s)) {
					continue;
				}
				if (params.get(s) instanceof Iterable<?>) {
					Iterable<?> ite = (Iterable<?>) params.get(s);
					for (Object i : ite) {
						builder.append(s).append("=").append(i).append("&");
					}
				} else {
					builder.append(s).append("=").append(params.get(s)).append("&");
				}
			}
			builder.delete(builder.length() - 1, builder.length());
			log.info(String.format("http request %s", builder));
			URL destURL = new URL(builder.toString());
			HttpURLConnection urlConn = (HttpURLConnection) destURL.openConnection();
			urlConn.setConnectTimeout(5000);
			urlConn.setReadTimeout(40000);
			urlConn.setDoOutput(true);
			urlConn.setDoInput(true);
			urlConn.setAllowUserInteraction(false);
			urlConn.setUseCaches(false);
			urlConn.setRequestMethod("GET");
			urlConn.connect();
			in = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "UTF-8"));
			String s = null;
			while ((s = in.readLine()) != null) {
				connResult.append(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return connResult.toString().trim();
	}
}
